package com.ruoyi.tokenTools;

import com.cyl.manager.ums.domain.entity.UserInfo;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.framework.config.LocalDataUtil;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.FhUser;
import com.ruoyi.system.service.impl.FhUserServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//拦截器方法执行器
@Configuration
public class LoginInterceptor extends HandlerInterceptorAdapter {
    /**
     * 目标方法执行前
     * 该方法在控制器处理请求方法前执行，其返回值表示是否中断后续操作
     * 返回 true 表示继续向下执行，返回 false 表示中断后续操作
     *
     * @return
     */
    @Resource
    private TokenService tokenService;

    @Autowired
    private FhUserServiceImpl fhUserService;

    //    导入redis配置
    @Autowired
    @Qualifier("stringRedisTemplate")
    RedisTemplate<String, String> rt;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    //放行接口
    private static String[] WHITE_PATHS = {
            "/app/userCode",
            "/app/userRegister",
            "/app/userLogin",
            "/app/phoneLogin",
            "/app/wxLogin",
            "/app/qqLogin",
            "/app/userResetPasswords",
            "/app/userResetAccount",
            "/app/getAdminToken",
            "/app/registerImUser"
    };

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestUri = request.getRequestURI();
        boolean flag = true;
        //若访问前缀不是”app“且参数齐全，直接放行
        if (!requestUri.startsWith("/app/")) {
            return super.preHandle(request, response, handler);
        }
        //如果为上面声明的地址，直接放行
        for (String s : WHITE_PATHS) {
            if (requestUri.startsWith(s)) {
                flag = false;
                break;
            }
        }
        if (!flag) {
            return super.preHandle(request, response, handler);
        }
        try{
            //获取token，用户信息
            String token = tokenService.getToken(request);
            LoginUser loginUser = tokenService.getLoginUser(request);
            // 获取 token 中的 account
            String account = loginUser.getUser().getUserName();
            Long userId = loginUser.getUser().getUserId();
            FhUser fhUser = fhUserService.selectFhUserById(userId);
            UserInfo userInfo = new UserInfo();
//            userInfo.setId(fhUser.getId());
            BeanUtils.copyProperties(fhUser,userInfo);
            //取出用户id存入线程域中
            LocalDataUtil.setVar(Constants.MEMBER_INFO, userInfo);
//        UserThreadLocal.set(userId);
            //取出验证码
            ValueOperations<String, String> Value = rt.opsForValue();
            ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
            String old_token = ops.get(account + "_token");
            if (old_token == null) {
                throw new ServiceException("token过期", HttpStatus.UNAUTHORIZED);
            } else if (old_token.equals(token)) {
                return true;
            }
        }catch (Exception e){
            throw new ServiceException("token错误或过期", HttpStatus.UNAUTHORIZED);
        }
        throw new ServiceException("token错误或过期", HttpStatus.UNAUTHORIZED);



//        String token = tokenService.getToken(request);// 从 http 请求头中取出 token
//        // 如果不是映射到方法直接通过
//        if (!(handler instanceof HandlerMethod)) {
//            return true;
//        }
//        HandlerMethod handlerMethod = (HandlerMethod) handler;
//        Method method = handlerMethod.getMethod();
//
//        //检查方法是否有passtoken注解，有则跳过认证，直接通过
//        if (method.isAnnotationPresent(PassToken.class)) {
//            PassToken passToken = method.getAnnotation(PassToken.class);
//            if (passToken.required()) {
//                return true;
//            }
//        }
//
//        //检查有没有需要用户权限的注解
//        if (method.isAnnotationPresent(UserLoginToken.class)) {
//            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
//            if (userLoginToken.required()) {
//                // 执行认证
//                if (token == ""||token==null) {
//                    throw new ServletException("token为空");
//                }
//
//                // 获取 token 中的 account
//                try {
//
//                    LoginUser loginUser = tokenService.getLoginUser(request);
//                    String account = loginUser.getUser().getUserName();
//                    Long userId = loginUser.getUser().getUserId();
//                    //取出用户id存入线程域中
//                    UserThreadLocal.set(userId);
//
//                    //取出验证码
//                    ValueOperations<String, String> Value = rt.opsForValue();
//                    ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
//                    String old_token = ops.get(account + "_token");
//
//                    if(old_token ==null){
//                        throw new ServiceException("token过期",HttpStatus.UNAUTHORIZED);
//                    }
//                    else if(old_token.equals(token)) {
//                        return true;
//                    }
//                }catch (Exception e){
//                    throw new ServiceException("token错误", HttpStatus.UNAUTHORIZED);
//                }
//            }
//        }
//        throw new ServiceException("token错误或过期", HttpStatus.UNAUTHORIZED);
    }

}
